package com.gr.smartedubackend.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gr.smartedubackend.common.BaseResponse;
import com.gr.smartedubackend.common.BusinessException;
import com.gr.smartedubackend.common.DeleteRequest;
import com.gr.smartedubackend.common.ErrorCode;
import com.gr.smartedubackend.constant.UserConstant;
import com.gr.smartedubackend.model.dto.student.StudentAddRequest;
import com.gr.smartedubackend.model.dto.student.StudentQueryByTeacherDto;
import com.gr.smartedubackend.model.dto.student.StudentQueryRequest;
import com.gr.smartedubackend.model.dto.student.StudentUpdateRequest;
import com.gr.smartedubackend.model.entity.Student;
import com.gr.smartedubackend.model.entity.StudentGroup;
import com.gr.smartedubackend.model.entity.User;
import com.gr.smartedubackend.service.StudentGroupService;
import com.gr.smartedubackend.service.StudentService;
import com.gr.smartedubackend.service.UserService;
import com.gr.smartedubackend.utils.ResultUtils;
import com.gr.smartedubackend.utils.ThrowUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/student")
public class StudentController {

    @Resource
    private StudentService studentService;

    @Resource
    private StudentGroupService studentGroupService;

    @Resource
    private UserService userService;

    @PostMapping("/add")
    @Transactional
    public BaseResponse<Long> addStudent(@RequestBody StudentAddRequest studentAddRequest) {
        ThrowUtils.throwIf(studentAddRequest == null, ErrorCode.PARAMS_ERROR);
        Long classId = studentAddRequest.getClassId();
        if (classId == null || classId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        StudentGroup studentGroup = studentGroupService.getById(classId);
        if (studentGroup == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "班级不存在");
        }
        Integer studentNum = studentGroup.getStudentNum();
        studentGroup.setStudentNum(studentNum + 1);
        boolean result = studentGroupService.updateById(studentGroup);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        studentAddRequest.setClassName(studentGroup.getClassName());
        Student student = new Student();
        BeanUtils.copyProperties(studentAddRequest, student);
        result = studentService.save(student);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        User user = new User();
        user.setUserAccount(student.getStudentNumber());
        String encryptPassword = userService.getEncryptPassword(UserConstant.DEFAULT_PASSWORD);
        user.setUserPassword(encryptPassword);
        user.setUserName(student.getStudentName());
        user.setUserAvatar(student.getStudentAvatar());
        user.setUserRole(UserConstant.STUDENT_ROLE);
        result = userService.save(user);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);

        return ResultUtils.success(student.getId());
    }

    @GetMapping("/get")
    public BaseResponse<Student> getStudentById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        Student student = studentService.getById(id);
        ThrowUtils.throwIf(student == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(student);
    }

    @GetMapping("/get/byNumber")
    public BaseResponse<Student> getStudentByNumber(String studentNumber) {
        ThrowUtils.throwIf(StringUtils.isBlank(studentNumber), ErrorCode.PARAMS_ERROR);
        Student student = studentService.getOne(new QueryWrapper<Student>().eq("studentNumber", studentNumber));
        ThrowUtils.throwIf(student == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(student);
    }

    @PostMapping("/list/page")
    public BaseResponse<Page<Student>> listStudentByPage(@RequestBody StudentQueryRequest studentQueryRequest) {
        ThrowUtils.throwIf(studentQueryRequest == null, ErrorCode.PARAMS_ERROR);
        int current = studentQueryRequest.getCurrent();
        int pageSize = studentQueryRequest.getPageSize();
        Page<Student> studentPage = studentService.page(new Page<>(current, pageSize),
                studentService.getQueryWrapper(studentQueryRequest));
        return ResultUtils.success(studentPage);
    }

    @PostMapping("/list/page/byTeacher")
    public BaseResponse<Page<Student>> listStudentByPageByTeacher(@RequestBody StudentQueryByTeacherDto studentQueryByTeacherDto) {
        ThrowUtils.throwIf(studentQueryByTeacherDto == null, ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(studentService.listStudentByPageByTeacher(studentQueryByTeacherDto));
    }

    @PostMapping("/list")
    public BaseResponse<List<Student>> listStudent(@RequestBody StudentQueryRequest studentQueryRequest) {
        ThrowUtils.throwIf(studentQueryRequest == null, ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(studentService.list(studentService.getQueryWrapper(studentQueryRequest)));
    }

    @PostMapping("/update")
    @Transactional
    public BaseResponse<Boolean> updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
        ThrowUtils.throwIf(studentUpdateRequest == null || studentUpdateRequest.getId() <= 0, ErrorCode.PARAMS_ERROR);
        String className = studentService.updateClassStudentNum(studentUpdateRequest);
        studentUpdateRequest.setClassName(className);
        Student student = new Student();
        BeanUtils.copyProperties(studentUpdateRequest, student);
        boolean result = studentService.updateById(student);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteStudent(@RequestBody DeleteRequest deleteRequest) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() <= 0, ErrorCode.PARAMS_ERROR);
        boolean result = studentService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }
}
